//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using OpenLS.Chart.Internals;
using OpenLS.Core.Serialization;

namespace OpenLS.Chart
{
    public class LineSeries : Series, INumericValuesProvider, IMarkerOwner, IDataPointOwner, IDataLabelsOwner
    {
        private NumericDataSource _val;
        private DataSource cat;
        private readonly DataPoints _dataPoints = new DataPoints();
        private DataLabels dlbls;
        private ErrorBars errorBars;
        private Marker _marker;
        private bool _isSmooth;
        private ObservableCollection<TrendLine> trendLines = new ObservableCollection<TrendLine>();

        public Marker Marker
        {
            get { return _marker; }
            set { _marker = value; notifyPropertyChanged("Marker");}
        }

        public DataPoints DataPoints
        {
            get { return _dataPoints; }
        }

        public ObservableCollection<TrendLine> TrendLines
        {
            get { return trendLines; }
            set { trendLines = value; notifyPropertyChanged("TrendLines");}
        }

        public ErrorBars ErrorBars
        {
            get { return errorBars; }
            set { errorBars = value; notifyPropertyChanged("ErrorBars");}
        }

        public DataSource Categories
        {
            get { return cat; }
            set { cat = value;notifyPropertyChanged("Categories"); }
        }

        public NumericDataSource Values
        {
            get { return _val; }
            set
            {
                if (_val != null)
                    _val.ValueChanged -= numericDataSource_ValueChanged;
                _val = value;
                notifyPropertyChanged("Values");
                if (_val != null)
                    _val.ValueChanged += numericDataSource_ValueChanged;
            }
        }


        public bool IsSmooth
        {
            get { return _isSmooth; }
            set { _isSmooth = value;notifyPropertyChanged("IsSmooth"); }
        }


        public DataLabels DataLabels
        {
            get { return dlbls; }
            set { dlbls = value; notifyPropertyChanged("DataLabels");}
        }

        #region INumericValuesProvider Members

        IEnumerable<NumericValue> INumericValuesProvider.GetValues()
        {
            return Values.NumericValues;
        }


        public event EventHandler ValueChanged;

        #endregion

        private void numericDataSource_ValueChanged(object sender, EventArgs e)
        {
            if (ValueChanged != null)
                ValueChanged(sender, e);
        }

        internal override void ReadXmlCore(ReadContext context)
        {
            using (var c = context.Read("ser"))
            {
                ReadXmlBase(c);
                Marker = c.ReadOptionalElement<Marker>("marker");
                while (c.ReaderLocalName == "dPt")
                {
                    DataPoints.Add(c.ReadElement<DataPoint>());
                }
                DataLabels = c.ReadOptionalElement<DataLabels>(DataLabels.xmlName);
                var trendLine = c.ReadOptionalElement<TrendLine>(TrendLine.xmlName);
                while (trendLine != null)
                {
                    TrendLines.Add(trendLine);
                    trendLine = c.ReadOptionalElement<TrendLine>(TrendLine.xmlName);
                }
                errorBars = c.ReadOptionalElement<ErrorBars>(ErrorBars.xmlName);
                Categories = DataSource.ReadOptionalDataSource("cat", c);
                Values = NumericDataSource.ReadOptionalNumericDataSource("val", c);
                IsSmooth = c.ReadOptionalElementBooleanAttribute("smooth", false);
                c.WarnIf("crtExt");
            }
        }

        internal override void WriteXmlCore(WriteContext context)
        {
            using (WriteContext c = context.Write("ser"))
            {
                WriteXmlBase(c);
                c.WriteOptionalElement(Marker);
                foreach (DataPoint dPt in DataPoints)
                    c.WriteElement(dPt);
                c.WriteOptionalElement(DataLabels);
                foreach (TrendLine l in trendLines)
                    c.WriteElement(l);
                c.WriteOptionalElement(errorBars);
                WriteOptionalNumericDataSource("cat", Categories, c);
                WriteOptionalNumericDataSource("val", Values, c);
                c.WriteOptionalElementBooleanAttribute("smooth", IsSmooth, false);
                c.WarnIf("crtExt");
            }
        }
    }
}